package com.gsafety.cloudframework.api.oauth.cfg;

import java.util.concurrent.TimeUnit;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;

import com.gsafety.cloudframework.api.oauth.service.CFWJdbcClientDetailsService;

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

    @Autowired
    AuthenticationManager authenticationManager;
    @Autowired
    RedisConnectionFactory redisConnectionFactory;

    @Autowired
    private DataSource dataSource;
    
    
    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        //允许表单认证
        oauthServer.allowFormAuthenticationForClients();
        
    	oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("permitAll()");
    }

    @Bean
    public ClientDetailsService clientDetails() {
    	ClientDetailsService service = new CFWJdbcClientDetailsService(dataSource);
        return service;
    }
    
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    	/** */
    	clients.withClientDetails(clientDetails());
    	
    	/**
    	clients.jdbc(dataSource)
.passwordEncoder(passwordEncoder)

.withClient("my-trusted-client")
.authorizedGrantTypes("password", "authorization_code",
"refresh_token", "implicit")
.authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
.scopes("read", "write", "trust")
.resourceIds("oauth2-resource")
.accessTokenValiditySeconds(60)


.and()
.withClient("my-client-with-registered-redirect")
.authorizedGrantTypes("authorization_code")
.authorities("ROLE_CLIENT").scopes("read", "trust")
.resourceIds("oauth2-resource")
.redirectUris("http://anywhere?key=value").and()


.withClient("my-client-with-secret")
.authorizedGrantTypes("client_credentials", "password")
.authorities("ROLE_CLIENT").scopes("read")
.resourceIds("oauth2-resource").secret("secret"); 

    	 
    	clients.jdbc(dataSource)
    	       .withClient("client_1")
        .resourceIds(OAuth2ServerConfig.DEMO_RESOURCE_ID)
        .authorizedGrantTypes("client_credentials", "refresh_token")
        .scopes("select")
        .authorities("client")
        .secret("123456")
        .and()
        .withClient("client_2")
        .resourceIds(OAuth2ServerConfig.DEMO_RESOURCE_ID)
        .authorizedGrantTypes("password", "refresh_token")
        .scopes("select")
        .authorities("client")
        .secret("123456");
    	*/
    	
    	/**
        //配置两个客户端,一个用于password认证一个用于client认证
        clients.inMemory()
        
                .withClient("client_1")
                .resourceIds(OAuth2ServerConfig.DEMO_RESOURCE_ID)
                .authorizedGrantTypes("client_credentials", "refresh_token")
                .scopes("select")
                .authorities("client")
                .secret("123456")
                
                
                .and()
                .withClient("client_2")
                .resourceIds(OAuth2ServerConfig.DEMO_RESOURCE_ID)
                .authorizedGrantTypes("password", "refresh_token")
                .scopes("select")
                .authorities("client")
                .secret("123456");
                
                 */
    }

//    @Bean
//    public TokenStore tokenStore() {
//    	return new RedisTokenStore(redisConnectionFactory);
//    }
    
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.tokenStore(new RedisTokenStore(redisConnectionFactory))
                .authenticationManager(authenticationManager);
    }

    @Bean
    @Primary
    public DefaultTokenServices tokenServices(){
    	final DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
    	defaultTokenServices.setTokenStore(new RedisTokenStore(redisConnectionFactory));
    	defaultTokenServices.setSupportRefreshToken(true);
    	return defaultTokenServices;
    }

}
